package com.nanbei.a16;

import com.nanbei.a15.A15;
import org.aspectj.weaver.patterns.AnnotationPointcut;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.StaticMethodMatcher;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;

/**
 * a.底层切点实现是如何匹配的: 调用aspectJ的匹配方法
 * b.比较关键的是它实现了MethodMatcher接口，用来执行方法的匹配
 *
 * @ClassDescription:
 * @JdkVersion: 1.8
 * @Author: libs
 * @Created: 2024/11/19 14:13
 */
public class A16 {
    public static void main(String[] args) throws NoSuchMethodException {
        // 定义切点
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(* bar())");
        System.out.println(pointcut.matches(T1.class.getMethod("foo"), T1.class));
        System.out.println(pointcut.matches(T1.class.getMethod("bar"), T1.class));

        // 根据注解来定义切点
        AspectJExpressionPointcut pointcut1 = new AspectJExpressionPointcut();
        pointcut1.setExpression("@annotation(org.springframework.transaction.annotation.Transactional)");
        System.out.println(pointcut1.matches(T1.class.getMethod("foo"), T1.class));
        System.out.println(pointcut1.matches(T1.class.getMethod("bar"), T1.class));

        System.out.println(">>>>>>>> 自定义切点 >>>>>>>>>>>>>>>");
        StaticMethodMatcherPointcut pointcut2 = new StaticMethodMatcherPointcut() {
            @Override
            public boolean matches(Method method, Class<?> targetClass) {
                // 查找方法上是否存在注解
                MergedAnnotations annotations = MergedAnnotations.from(method);
                if (annotations.isPresent(Transactional.class)){
                    return true;
                }
                // 查找类 和 接口上是否存在注解
                // TYPE_HIERARCHY 对整个类型层次结构执行完整搜索，包括超类和实现的接口。
                annotations = MergedAnnotations.from(targetClass, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY);
                if (annotations.isPresent(Transactional.class)){
                    return true;
                }
                return false;
            }
        };
        System.out.println(pointcut2.matches(T1.class.getMethod("foo"), T1.class));
        System.out.println(pointcut2.matches(T1.class.getMethod("bar"), T1.class));
        System.out.println(pointcut2.matches(T2.class.getMethod("foo"), T2.class));
        System.out.println(pointcut2.matches(T3.class.getMethod("foo"), T3.class));
    }


    static class T1 {
        @Transactional
        public void foo() {
        }

        public void bar() {
        }

    }

    @Transactional
    static class T2 {
        public void foo() {
        }
    }

    @Transactional
    interface I1 {
        void foo();
    }

    static class T3 implements I1 {
        public void foo() {
        }
    }
}


